﻿#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "module_interface.h"
#include "module_loader.h"
#include "modbus_manager.h"
#include <QToolBar>
#include <QToolButton>
#include <QVBoxLayout>
#include <QButtonGroup>
#include <QFileDialog>
#include <QMessageBox>
#include <QCloseEvent>
#include <QDebug>
#include <QSerialPortInfo>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui_(new Ui::MainWindow)
    , moduleLoader_(new ModuleLoader(this))
    , modbusManager_(new ModbusManager(this))
{
    ui_->setupUi(this);
    setWindowTitle(u8"综合平台编辑器");
    setWindowIcon(QIcon(":/resource/image/editor.png"));
    
    // 加载模块库
    if (!moduleLoader_->loadModules())
    {
        QMessageBox::critical(this, u8"错误", u8"无法加载任何模块库，应用程序无法正常运行。");
        return;
    }
    
    // 创建所有可用模块
    QStringList availableModules = moduleLoader_->getAvailableModules();
    for (const QString& moduleName : availableModules)
    {
        IModule* module = moduleLoader_->createModule(moduleName, this, modbusManager_, this);
        if (module)
        {
            modules_[moduleName] = module;
            setupModuleConnections(module);
            module->setModbusManager(modbusManager_);
            module->init();
        }
    }
    
    // 设置默认模块
    if (!availableModules.isEmpty())
    {
        currentModuleName_ = availableModules.first();
    }
    
    // 初始化串口配置，优先使用COM20，如果不存在则使用第一个可用串口
    const auto infos = QSerialPortInfo::availablePorts();
    bool foundCom20 = false;
    for (const QSerialPortInfo &info : infos) {
        if (info.portName() == "COM20") {
            foundCom20 = true;
            break;
        }
    }
    
    if (foundCom20) {
        currentSerialPort_ = "COM20";
    } else if (!infos.isEmpty()) {
        currentSerialPort_ = infos.first().portName();
    } else {
        currentSerialPort_ = "COM1"; // 默认值，即使不存在
    }
    currentSerialPort_ = "COM20";
    currentBaudRate_ = 19200;
    currentDataBits_ = QSerialPort::Data8;
    currentStopBits_ = QSerialPort::OneStop;
    currentParity_ = QSerialPort::EvenParity;
    
    // 连接菜单信号
    connect(ui_->actionNew, &QAction::triggered, this, &MainWindow::onNewFile);
    connect(ui_->actionOpen, &QAction::triggered, this, &MainWindow::onOpenFile);
    connect(ui_->actionSave, &QAction::triggered, this, &MainWindow::onSaveFile);
    connect(ui_->actionStart, &QAction::triggered, this, &MainWindow::startSimulation);
    connect(ui_->actionStop, &QAction::triggered, this, &MainWindow::stopSimulation);
    
    // 连接ModbusManager信号
    connect(modbusManager_, &ModbusManager::logMessage, this, &MainWindow::appendLog);
}

MainWindow::~MainWindow()
{
    // 清理模块资源
    for (auto it = modules_.begin(); it != modules_.end(); ++it)
    {
        delete it.value();
    }
    modules_.clear();
}

// 实现槽函数
void MainWindow::appendLog(const QString& message)
{
    ui_->textEdit->append(message);
}

// 辅助函数：获取当前激活的模块
IModule* MainWindow::getCurrentModule()
{
    // 根据当前选中的tab索引决定操作哪个模块
    int currentTab = ui_->tabWidget->currentIndex();

    if (currentTab == 0)
    {  // PLC页面
        IModule* plcModule = modules_.value(u8"PLC");
        if (!plcModule)
        {
            QMessageBox::warning(this, u8"警告", u8"PLC模块不可用，请检查PLC库是否正确加载。");
        }
        return plcModule;
    } 
    else if (currentTab == 1)
    {  // HMI页面
        IModule* hmiModule = modules_.value(u8"HMI");
        if (!hmiModule)
        {
            QMessageBox::warning(this, u8"警告", u8"HMI模块不可用，请检查HMI库是否正确加载。");
        }
        return hmiModule;
    }
    return nullptr;  // 其他
}

void MainWindow::setupModuleConnections(IModule* module)
{
    if (module)
    {
        connect(module, &IModule::logMessageGenerated, this, &MainWindow::appendLog);
        connect(module, &IModule::signalAddressChanged, this, [this](int oldAddr, int newAddr){
            if (!modbusManager_) return;
            modbusManager_->removeMonitoredCoil(oldAddr);
            modbusManager_->addMonitoredCoil(newAddr);
        });
        connect(module, &IModule::signalRegisterChanged, this, [this](int oldAddr, int newAddr){
            if (!modbusManager_) return;
            modbusManager_->removeMonitoredRegister(oldAddr);
            modbusManager_->addMonitoredRegister(newAddr);
        });
        // 连接写线圈请求信号（所有模块都继承自IModule，所以可以直接连接）
        connect(module, &IModule::writeCoilRequested, this, [this](int address, bool value) {
            // 在主项目中安全地调用ModbusManager
            if (modbusManager_)
            {
                modbusManager_->writeCoil(address, value);
                appendLog(QString(u8"主项目处理模块写线圈请求：地址%1，值%2").arg(address).arg(value ? u8"ON" : u8"OFF"));
            }
        });

        connect(module, &IModule::writeRegiseterRequested, this, [this](int address, quint16 value) {
            // 在主项目中安全地调用ModbusManager
            if (modbusManager_)
            {
                modbusManager_->writeRegister(address, value);
                //appendLog(QString(u8"主项目处理模块写线圈请求：地址%1，值%2").arg(address).arg(value ? u8"ON" : u8"OFF"));
            }
        });
        
        // 连接ModbusManager的信号到模块
        if (modbusManager_)
        {
            // 直接连接ModbusManager的信号到模块的接口方法
            connect(modbusManager_, &ModbusManager::coilUpdated, module, &IModule::onCoilUpdated);
            connect(modbusManager_, &ModbusManager::registerUpdated, module, &IModule::onRegisterUpdated);
        }
    }
}

// 新建菜单动作槽函数
void MainWindow::onNewFile()
{
    IModule* currentModule = getCurrentModule();
    if (!currentModule)
    {
        QMessageBox::warning(this, u8"警告", u8"当前模块不可用，无法执行新建操作。");
        return;
    }

    // 检查修改状态
    if (currentModule->isModified())
    {
        auto ret = QMessageBox::warning(this, u8"提示", u8"当前文件有未保存的更改，是否保存？",
                                        QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);

        if (ret == QMessageBox::Save)
        {
            onSaveFile();  // 保存当前文件
        }
        else if (ret == QMessageBox::Cancel)
        {
            return;  // 取消新建
        }
    }

    // 执行新建操作
    currentModule->reset();
}

// 获取文件过滤器
QString MainWindow::getFileFilter(IModule* module)
{
    if (module)
    {
        return module->getFileFilter();
    }
    return "";
}

// 执行文件操作
bool MainWindow::fileOperation(IModule* module, const QString& fileName, bool isOpen)
{
    if (module)
    {
        return isOpen ? module->openFromFile(fileName) : module->saveToFile(fileName);
    }
    return false;
}

void MainWindow::onOpenFile()
{
    IModule* module = getCurrentModule();
    if (!module) 
    {
        QMessageBox::warning(this, u8"警告", u8"当前模块不可用，无法执行打开操作。");
        return;
    }

    // 获取文件过滤器
    QString filter = getFileFilter(module);
    if (filter.isEmpty()) return;

    // 获取文件名
    QString fileName = QFileDialog::getOpenFileName(this, u8"打开文件", "../../../file/", filter);
    if (fileName.isEmpty()) return;

    // 执行打开操作
    bool isSuccess = fileOperation(module, fileName, true);

    if (!isSuccess)
    {
        QMessageBox::warning(this, u8"打开失败", u8"文件打开失败");
    }
}

void MainWindow::onSaveFile()
{
    IModule* module = getCurrentModule();
    if (!module) 
    {
        QMessageBox::warning(this, u8"警告", u8"当前模块不可用，无法执行保存操作。");
        return;
    }

    // 获取文件过滤器
    QString filter = getFileFilter(module);
    if (filter.isEmpty()) return;

    // 获取文件名
    QString fileName = QFileDialog::getSaveFileName(this, u8"保存文件", "../../../file/", filter);
    if (fileName.isEmpty()) return;

    // 执行保存操作
    bool isSuccess = fileOperation(module, fileName, false);

    if (!isSuccess)
    {
        QMessageBox::warning(this, u8"保存失败", u8"文件保存失败！");
    }
}

void MainWindow::startSimulation()
{
    // 使用统一的ModbusManager启动仿真
    if (modbusManager_->isRunning())
    {
        appendLog(u8"仿真已经在运行中");
        return;
    }
    
    bool success = modbusManager_->startSimulation(currentSerialPort_, currentBaudRate_, 
                                                  currentParity_, currentDataBits_, currentStopBits_);
    if (success)
    {
        appendLog(QString(u8"仿真已启动：串口：%1，波特率：%2")
                 .arg(currentSerialPort_, QString::number(currentBaudRate_)));
        
        // 通知所有模块仿真已启动
        for (auto it = modules_.begin(); it != modules_.end(); ++it)
        {
            IModule* module = it.value();
            if (module)
            {
                module->startSimulation(currentSerialPort_, currentBaudRate_,
                                      currentDataBits_, currentStopBits_, currentParity_);
            }
        }
    }
    else
    {
        appendLog(u8"仿真启动失败");
    }
}

void MainWindow::stopSimulation()
{
    // 使用统一的ModbusManager停止仿真
    if (!modbusManager_->isRunning())
    {
        appendLog(u8"仿真未在运行");
        return;
    }
    
    // 通知所有模块仿真即将停止
    for (auto it = modules_.begin(); it != modules_.end(); ++it)
    {
        IModule* module = it.value();
        if (module)
        {
            module->stopSimulation();
        }
    }
    
    modbusManager_->stopSimulation();
    appendLog(u8"仿真已停止");
}
